using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace BNode.Expressions
{
    public class ExprBuilderUtility
    {
        private static ExprBuilder _builder;
        public static ExprBuilder Ins
        {
            get
            {
                _builder ??= new ExprBuilder();
                return _builder;
            }
        }
        public static ExprBuilder InsCleared => Ins.Clear();
        /// StringBuilder的快速构造方法
        /// </summary>
        public static readonly Func<ExprBuilder> CreateExprBuilderFunc = InitExprBuilderFunc();

        private static Func<ExprBuilder> InitExprBuilderFunc()
        {
            var paramTypes = Type.EmptyTypes;
            var cons = typeof(ExprBuilder).GetConstructor(paramTypes);
            var exprBuilder = new ExprBuilder().Return(cons.New());
            var func = exprBuilder.Func<ExprBuilder>().Compile();
            return func;
        }
        private static readonly ConcurrentQueue<ExprBuilder> _builderPool = new();
        /// <summary>
        /// 不要在使用GetBuilder()的过程中再次GetBuilder()！
        /// </summary>
        /// <returns></returns>
        public static ExprBuilder GetBuilder()
        {
            if (!_builderPool.TryDequeue(out var builder))
            {
                builder = ExprBuilderUtility.CreateExprBuilderFunc.Invoke();
            }
            try
            {
                return builder.Clear();
            }
            finally
            {
                _builderPool.Enqueue(builder);
            }
        }
    }
}
